using System;
using System.Runtime.CompilerServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;

namespace AnimCollections {
    public static unsafe class AnimNativeUtility {

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void* GetNativeArrayBufferPointer<T>(NativeArray<T> array) where T : unmanaged {
            return array.m_Buffer;
        }

        /// <summary>
        /// 用完整数据填充 NativeArray 的存储内存
        /// </summary>
        /// <param name="size"> in bytes </param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void FillNativeArray<T>(NativeArray<T> dest, void* src, long size) where T : unmanaged {
            UnsafeUtility.MemCpy(dest.m_Buffer, src, size);
        }
        
        /// <summary>
        /// 用完整数据填充 NativeSimpleArray 的存储内存
        /// </summary>
        /// <param name="size"> in bytes </param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void FillNativeArray<T>(NativeSimpleArray<T> dest, void* src, long size) where T : unmanaged {
            UnsafeUtility.MemCpy(dest.m_Buffer, src, size);
        }

        /// <summary>
        /// 将前半数据拷贝到后半，再将前半清0
        /// </summary>
        /// <param name="array"></param>
        /// <param name="size"> in bytes </param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void CacheAndClear<T>(NativeSimpleArray<T> array, long size) where T : unmanaged {
            var destPtr = (byte*)array.m_Buffer + size;
            UnsafeUtility.MemCpy(destPtr, array.m_Buffer, size);
            UnsafeUtility.MemClear(array.m_Buffer, size);
        }
        /// <summary>
        /// 全部清0
        /// </summary>
        /// <param name="array"></param>
        /// <param name="size"> in bytes </param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Clear<T>(NativeSimpleArray<T> array, long size) where T : unmanaged {
            UnsafeUtility.MemClear(array.m_Buffer, size);
        }

        /// <summary>
        /// 深拷贝字典的内容
        /// </summary>
        public static void DeepCloneHashMap<TK, TV>(out UnsafeHashMap<TK, TV> dest, in UnsafeHashMap<TK, TV> src, AllocatorManager.AllocatorHandle allocator) where TK : unmanaged, IEquatable<TK> where TV : unmanaged {
            int capacity = src.m_Data.Capacity;
            var totalSize = (long)src.m_Data.Buckets - (long)src.m_Data.Ptr + src.m_Data.BucketCapacity * sizeof(int);

            dest = new UnsafeHashMap<TK, TV>(capacity, allocator);
            UnsafeUtility.MemCpy(dest.m_Data.Ptr, src.m_Data.Ptr, totalSize);
            dest.m_Data.Count = src.m_Data.Count;
            dest.m_Data.AllocatedIndex = src.m_Data.AllocatedIndex;
            dest.m_Data.FirstFreeIdx = src.m_Data.FirstFreeIdx;
        }

    }
}
